﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Security.Cryptography;
using System.Web;
using System.Web.Script.Serialization;
using System.Web.UI;
using System.Web.Mvc;
//using Xmlt.Sample.Models;

namespace Xmlt.Sample.Controllers
{
    public class AutoCompleteRequest
    {
        public string PrefixText { get; set; }
        public int Count { get; set; }
    }

    internal class MyMethods
    {

        public string getDate()
        {
            return DateTime.Today.ToShortDateString();
        }

        public string getTime()
        {
            return DateTime.Now.ToLongTimeString();
        }

        public int add(int a, int b)
        {
            return a + b;
        }
    }

    public static class XmlExtensions
    {

        public static System.Xml.XPath.XPathNavigator CreateNavigator<targetType>(this targetType target)
        {
            if (target == null)
                return null;
            MemoryStream stream = new MemoryStream();
            System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(targetType));
            serializer.Serialize(stream, target);
            stream.SetLength(stream.Position);
            stream.Position = 0;
            System.Xml.XPath.XPathDocument doc = new System.Xml.XPath.XPathDocument(stream);
            return doc.CreateNavigator();

        }

    }

    public class ResourceHelper {

        public string GetString(string resourceKey) {
            return "Hello";
        }

    }
    
    [System.Xml.Serialization.XmlRoot]
    public class BasicModel
    {

        [System.Xml.Serialization.XmlElement]
        public string Message
        {
            get
            {
                return "G'day World";
            }
            set { }
        }
    }

    [System.Xml.Serialization.XmlRoot]
    public class MessageCollection
    {

        [System.Xml.Serialization.XmlElement]
        public string[] Message
        {
            get;
            set;
        }
    }

    public class HomeController : Controller
    {
        public virtual ActionResult Index()
        {
            return View(1);
        }

        [HttpGet]
        public virtual ActionResult SampleBasic()
        {
            ViewData.Add("step", 1);
            return View(new BasicModel());
        }

        public ActionResult SampleSimpleForm(string firstName, string lastName)
        {
            ViewData.Add("firstName", firstName ?? "");
            ViewData.Add("lastName", lastName ?? "");
            if (!string.IsNullOrEmpty(firstName) && !string.IsNullOrEmpty(lastName))
                ViewData.Add("message", "Success!");
            return View(new BasicModel());
        }

        protected override void HandleUnknownAction(string actionName)
        {
            //base.HandleUnknownAction(actionName);
            View(actionName, new BasicModel()).ExecuteResult(this.ControllerContext);
        }

        [HttpPost]
        [ActionName("Sample1")]
        public ActionResult BasicPost()
        {
            return View(new BasicModel());
        }

        [HttpGet]
        public virtual ActionResult SampleAreaCustomization()
        {
            ViewData.Add("step", 3);
            return View(new BasicModel());
        }

        [HttpGet]
        public virtual ActionResult SampleControlFlow()
        {
            MessageCollection collection = new MessageCollection
            {
                Message = new string[] {
                    "Message 1",
                    "Message 2",
                    "Message 3"
                }
            };

            return View(collection);
        }

        [HttpGet]
        public virtual ActionResult SampleRenderPartial(string language)
        {
            if (!string.IsNullOrEmpty(language))
                ViewData.Add("language", language);
            this.ViewData.Add("urn:resourceHelper", new ResourceHelper());
            return View(new BasicModel());
        }

        [HttpGet]
        public virtual ActionResult SampleControlTemplates()
        {
            return View(new BasicModel());
        }

        [HttpGet]
        public virtual ActionResult SampleXslt()
        {
            return View(new BasicModel());
        }

        [HttpGet]
        public virtual ActionResult SampleInlineXslt()
        {
            return View(new BasicModel());
        }

        [HttpGet]
        public virtual ActionResult SampleJavascript()
        {
            return View(new BasicModel());
        }

        [HttpGet]
        public virtual ActionResult SampleExtensions()
        {
            ViewData.Add("urn:myMethods", new MyMethods());
            return View(new BasicModel());
        }

        [HttpGet]
        public virtual ActionResult SampleExternalXml()
        {
            return View(new BasicModel());
        }

        [HttpGet]
        public virtual ActionResult SampleAjax()
        {
            ViewData.Add("urn:myMethods", new MyMethods());
            return View(new BasicModel());
        }

        public virtual ActionResult SampleAjaxContent()
        {
            ViewData.Add("urn:myMethods", new MyMethods());
            return View(new BasicModel());
        }

        [HttpGet]
        public virtual ActionResult SampleTemplateInclude()
        {
            return View(new BasicModel());
        }
    }

    

    public static class ControllerExtensions
    {
        /// <summary>
        /// Captures the HTML output by a controller action that returns a ViewResult
        /// </summary>
        /// <typeparam name="TController"></typeparam>
        /// <param name="controller"></param>
        /// <param name="viewName">The name of the view to execute</param>
        /// <returns>The HTML output from the view</returns>
        public static string CaptureView<TController>(this TController controller, string viewName)
        where TController : Controller
        {
            return CaptureView(controller, viewName, string.Empty, null);
        }

        /// <summary>
        /// Captures the HTML output by a controller action that returns a ViewResult
        /// </summary>
        /// <typeparam name="TController"></typeparam>
        /// <param name="controller"></param>
        /// <param name="viewName">The name of the view to execute</param>
        /// <param name="model">The model to pass to the view</param>
        /// <returns>The HTML output from the view</returns>
        public static string CaptureView<TController>(this TController controller, string viewName, object model)
        where TController : Controller
        {
            return CaptureView(controller, viewName, string.Empty, model);
        }

        /// <summary>
        /// Captures the HTML output by a controller action that returns a ViewResult
        /// </summary>
        /// <typeparam name="TController"></typeparam>
        /// <param name="controller"></param>
        /// <param name="viewName">The name of the view to execute</param>
        /// <param name="masterName">The master template to use for the view</param>
        /// <param name="model">The model to pass to the view</param>
        /// <returns>The HTML output from the view</returns>
        public static string CaptureAction<TController>(this TController controller, string actionName)
        where TController : Controller
        {
            // pass the current controller context to orderController
            var controllerContext = controller.ControllerContext;

            // replace the current context with a new context that writes to a string writer
            var existingContext = System.Web.HttpContext.Current;
            var existingContextBase = controllerContext.HttpContext;

            var writer = new StringWriter();
            var response = new HttpResponse(writer);
            var context = new HttpContext(existingContext.Request, response) { User = existingContext.User };
            System.Web.HttpContext.Current = context;
            controllerContext.HttpContext = new HttpContextWrapper(context);

            ViewContext viewContext = new ViewContext { Writer = writer };
            viewContext.HttpContext = new HttpContextWrapper(context);
            viewContext.RouteData = controller.RouteData;

            HtmlHelper helper = new HtmlHelper(viewContext, new SimpleViewDataContainer(controller.ViewData));

            string result = System.Web.Mvc.Html.ChildActionExtensions.Action(helper, actionName).ToString();

            // execute the result
            //result.ExecuteResult(controllerContext);

            // restore the old context
            System.Web.HttpContext.Current = existingContext;
            controllerContext.HttpContext = existingContextBase;
            return result;
        }

        public class SimpleViewDataContainer : IViewDataContainer
        {
            public SimpleViewDataContainer(ViewDataDictionary viewData)
            {
                ViewData = viewData;
            }

            public ViewDataDictionary ViewData
            {
                get;
                set;
            }
        }

        /// <summary>
        /// Captures the HTML output by a controller action that returns a ViewResult
        /// </summary>
        /// <typeparam name="TController"></typeparam>
        /// <param name="controller"></param>
        /// <param name="viewName">The name of the view to execute</param>
        /// <param name="masterName">The master template to use for the view</param>
        /// <param name="model">The model to pass to the view</param>
        /// <returns>The HTML output from the view</returns>
        public static string CaptureView<TController>(this TController controller, string viewName, string masterName, object model)
        where TController : Controller
        {
            // pass the current controller context to orderController
            var controllerContext = controller.ControllerContext;

            // replace the current context with a new context that writes to a string writer
            var existingContext = System.Web.HttpContext.Current;
            var existingContextBase = controllerContext.HttpContext;

            var writer = new StringWriter();
            var response = new HttpResponse(writer);
            var context = new HttpContext(existingContext.Request, response) { User = existingContext.User };
            System.Web.HttpContext.Current = context;
            controllerContext.HttpContext = new HttpContextWrapper(context);

            // execute the action

            if (model != null)
            {
                controller.ViewData.Model = model;
            }

            var result = new ViewResult
            {
                ViewName = viewName,
                MasterName = masterName,
                ViewData = controller.ViewData,
                TempData = controller.TempData
            };

            // execute the result
            result.ExecuteResult(controllerContext);

            // restore the old context
            System.Web.HttpContext.Current = existingContext;
            controllerContext.HttpContext = existingContextBase;
            return writer.ToString();
        }
    }
}
